package de.fusionfactory.corpora

import java.util.regex.Pattern
import java.util.regex.Matcher
import com.aliasi.util.Files
import java.text.ParseException
import com.google.common.base.Charsets
import java.nio.charset.Charset

/**
 * Created by Markus Ackermann.
 * No rights reserved. 
 */
class LeipzigCorpus {

    /** Pattern for names like tam_newscrawl_2011_30K-sources.txt */
    private final static Pattern namePattern =
        ~/(\p{Alpha}+)_(\p{Alpha}+)_(\d{4}(?:_\d{4})?)_(\d+[KM]{1})-([\p{Alpha}_]+)/
    /** Pattern for a line like  '5	content encoding	utf-8'*/
    private final static Pattern encodingPattern = ~/\d\tcontent\sencoding\t(\S+)/

    File metaFile

    String languageId, sourceType, sizeDesc, timeDesc, contentType
    String encodingString



    File getMetaFile() {
        if( !metaFile) { throw new IllegalStateException("Meta file path not set.") }
        if( !(metaFile.exists() && metaFile.canRead())) {
            throw new FileNotFoundException("Meta file '$metaFile.canonicalPath' does not exist or no read permission")
        }
        metaFile.canonicalFile
    }

    Charset getEncoding() {
        def key = Charset.availableCharsets().keySet().find{ it.equalsIgnoreCase getEncodingString() }
        Charset.forName(key)
    }


    String getEncodingString() {
        if(encodingString) { encodingString }
        else {
            String ret

            Charsets.UTF_8
            metaFile.eachLine { line ->
                if(line ==~ encodingPattern) {
                    ret = (line =~ encodingPattern)[0][1]
                    encodingString = ret
                }
            }
            return ret
        }
    }

    static LeipzigCorpus fromFile(File corpusFile) {
        def baseName = Files.baseName(corpusFile)
        LeipzigCorpus ret

        if (!(baseName ==~ namePattern))
            throw new ParseException("'$baseName does not parse against expected naming sheme for a Leipig " <<
                    "Wortschatz Corpus text file")
        else {
            Matcher groups = (baseName =~ namePattern)
            baseName.eachMatch(namePattern) { whole, lang, source, time, size, content ->
                ret = new LeipzigCorpus(languageId: lang, sourceType: source, sizeDesc: size,
                        timeDesc: time, contentType: content)
            }
            def buf = new StringBuffer(baseName)
            Matcher matcher = namePattern.matcher(buf)
            assert matcher.matches()
            def typeIndices = ['start', 'end'].collect() { matcher."$it"(5)}
            buf[typeIndices[0]..typeIndices[1]] = 'meta'
            buf << '.txt'
            ret.metaFile =  new File(buf.toString(), corpusFile.absoluteFile.parentFile)
            return ret
        }
    }
}


